home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-M68K / UACCESS.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  21KB  |  873 lines

  1. #ifndef __M68K_UACCESS_H
  2. #define __M68K_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <linux/sched.h>
  8. #include <asm/segment.h>
  9.  
  10. #define VERIFY_READ    0
  11. #define VERIFY_WRITE    1
  12.  
  13. /* We let the MMU do all checking */
  14. #define access_ok(type,addr,size) 1
  15.  
  16. extern inline int verify_area(int type, const void * addr, unsigned long size)
  17. {
  18.     return access_ok(type,addr,size)?0:-EFAULT;
  19. }
  20.  
  21. /*
  22.  * The exception table consists of pairs of addresses: the first is the
  23.  * address of an instruction that is allowed to fault, and the second is
  24.  * the address at which the program should continue.  No registers are
  25.  * modified, so it is entirely up to the continuation code to figure out
  26.  * what to do.
  27.  *
  28.  * All the routines below use bits of fixup code that are out of line
  29.  * with the main instruction path.  This means when everything is well,
  30.  * we don't even have to jump over them.  Further, they do not intrude
  31.  * on our cache or tlb entries.
  32.  */
  33.  
  34. struct exception_table_entry
  35. {
  36.     unsigned long insn, fixup;
  37. };
  38.  
  39. /* Returns 0 if exception not found and fixup otherwise.  */
  40. extern unsigned long search_exception_table(unsigned long);
  41.  
  42.  
  43. /*
  44.  * These are the main single-value transfer routines.  They automatically
  45.  * use the right size if we just have the right pointer type.
  46.  */
  47.  
  48. #define put_user(x, ptr)                \
  49. ({                            \
  50.     int __pu_err;                    \
  51.     typeof(*(ptr)) __pu_val = (x);            \
  52.     switch (sizeof (*(ptr))) {                \
  53.     case 1:                        \
  54.     __put_user_asm(__pu_err, __pu_val, ptr, b);    \
  55.     break;                        \
  56.     case 2:                        \
  57.     __put_user_asm(__pu_err, __pu_val, ptr, w);    \
  58.     break;                        \
  59.     case 4:                        \
  60.     __put_user_asm(__pu_err, __pu_val, ptr, l);    \
  61.     break;                        \
  62.     default:                        \
  63.     __pu_err = __put_user_bad();            \
  64.     break;                        \
  65.     }                            \
  66.     __pu_err;                        \
  67. })
  68. #define __put_user(x, ptr) put_user(x, ptr)
  69.  
  70. extern int __put_user_bad(void);
  71.  
  72. /*
  73.  * Tell gcc we read from memory instead of writing: this is because
  74.  * we do not write to any memory gcc knows about, so there are no
  75.  * aliasing issues.
  76.  */
  77. #define __put_user_asm(err,x,ptr,bwl)            \
  78. __asm__ __volatile__                    \
  79.     ("21:moves" #bwl " %2,%1\n"                \
  80.      "1:\n"                        \
  81.      ".section .fixup,\"ax\"\n"                \
  82.      "   .even\n"                    \
  83.      "2: movel %3,%0\n"                    \
  84.      "   jra 1b\n"                    \
  85.      ".previous\n"                    \
  86.      ".section __ex_table,\"a\"\n"            \
  87.      "   .align 4\n"                    \
  88.      "   .long 21b,2b\n"                \
  89.      "   .long 1b,2b\n"                    \
  90.      ".previous"                    \
  91.      : "=d"(err)                    \
  92.      : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
  93.  
  94. #define get_user(x, ptr)                    \
  95. ({                                \
  96.     int __gu_err;                        \
  97.     typeof(*(ptr)) __gu_val;                    \
  98.     switch (sizeof(*(ptr))) {                    \
  99.     case 1:                            \
  100.     __get_user_asm(__gu_err, __gu_val, ptr, b, "=d");    \
  101.     break;                            \
  102.     case 2:                            \
  103.     __get_user_asm(__gu_err, __gu_val, ptr, w, "=r");    \
  104.     break;                            \
  105.     case 4:                            \
  106.     __get_user_asm(__gu_err, __gu_val, ptr, l, "=r");    \
  107.     break;                            \
  108.     default:                            \
  109.     __gu_val = 0;                        \
  110.     __gu_err = __get_user_bad();                \
  111.     break;                            \
  112.     }                                \
  113.     (x) = __gu_val;                        \
  114.     __gu_err;                            \
  115. })
  116. #define __get_user(x, ptr) get_user(x, ptr)
  117.  
  118. extern int __get_user_bad(void);
  119.  
  120. #define __get_user_asm(err,x,ptr,bwl,reg)    \
  121. __asm__ __volatile__                \
  122.     ("1: moves" #bwl " %2,%1\n"            \
  123.      "2:\n"                    \
  124.      ".section .fixup,\"ax\"\n"            \
  125.      "   .even\n"                \
  126.      "3: movel %3,%0\n"                \
  127.      "   sub" #bwl " %1,%1\n"            \
  128.      "   jra 2b\n"                \
  129.      ".previous\n"                \
  130.      ".section __ex_table,\"a\"\n"        \
  131.      "   .align 4\n"                \
  132.      "   .long 1b,3b\n"                \
  133.      ".previous"                \
  134.      : "=d"(err), reg(x)            \
  135.      : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
  136.  
  137. static inline unsigned long
  138. __generic_copy_from_user(void *to, const void *from, unsigned long n)
  139. {
  140.     unsigned long tmp;
  141.     __asm__ __volatile__
  142.     ("   tstl %2\n"
  143.      "   jeq 2f\n"
  144.      "1: movesl (%1)+,%3\n"
  145.      "   movel %3,(%0)+\n"
  146.      "   subql #1,%2\n"
  147.      "   jne 1b\n"
  148.      "2: movel %4,%2\n"
  149.      "   bclr #1,%2\n"
  150.      "   jeq 4f\n"
  151.      "3: movesw (%1)+,%3\n"
  152.      "   movew %3,(%0)+\n"
  153.      "4: bclr #0,%2\n"
  154.      "   jeq 6f\n"
  155.      "5: movesb (%1)+,%3\n"
  156.      "   moveb %3,(%0)+\n"
  157.      "6:\n"
  158.      ".section .fixup,\"ax\"\n"
  159.      "   .even\n"
  160.      "7: movel %2,%%d0\n"
  161.      "71:clrl (%0)+\n"
  162.      "   subql #1,%%d0\n"
  163.      "   jne 71b\n"
  164.      "   lsll #2,%2\n"
  165.      "   addl %4,%2\n"
  166.      "   btst #1,%4\n"
  167.      "   jne 81f\n"
  168.      "   btst #0,%4\n"
  169.      "   jne 91f\n"
  170.      "   jra 6b\n"
  171.      "8: addql #2,%2\n"
  172.      "81:clrw (%0)+\n"
  173.      "   btst #0,%4\n"
  174.      "   jne 91f\n"
  175.      "   jra 6b\n"
  176.      "9: addql #1,%2\n"
  177.      "91:clrb (%0)+\n"
  178.      "   jra 6b\n"
  179.          ".previous\n"
  180.      ".section __ex_table,\"a\"\n"
  181.      "   .align 4\n"
  182.      "   .long 1b,7b\n"
  183.      "   .long 3b,8b\n"
  184.      "   .long 5b,9b\n"
  185.      ".previous"
  186.      : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  187.      : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
  188.      : "d0", "memory");
  189.     return n;
  190. }
  191.  
  192. static inline unsigned long
  193. __generic_copy_to_user(void *to, const void *from, unsigned long n)
  194. {
  195.     unsigned long tmp;
  196.     __asm__ __volatile__
  197.     ("   tstl %2\n"
  198.      "   jeq 3f\n"
  199.      "1: movel (%1)+,%3\n"
  200.      "22:movesl %3,(%0)+\n"
  201.      "2: subql #1,%2\n"
  202.      "   jne 1b\n"
  203.      "3: movel %4,%2\n"
  204.      "   bclr #1,%2\n"
  205.      "   jeq 4f\n"
  206.      "   movew (%1)+,%3\n"
  207.      "24:movesw %3,(%0)+\n"
  208.      "4: bclr #0,%2\n"
  209.      "   jeq 5f\n"
  210.      "   moveb (%1)+,%3\n"
  211.      "25:movesb %3,(%0)+\n"
  212.      "5:\n"
  213.      ".section .fixup,\"ax\"\n"
  214.      "   .even\n"
  215.      "60:addql #1,%2\n"
  216.      "6: lsll #2,%2\n"
  217.      "   addl %4,%2\n"
  218.      "   jra 5b\n"
  219.      "7: addql #2,%2\n"
  220.      "   jra 5b\n"
  221.      "8: addql #1,%2\n"
  222.      "   jra 5b\n"
  223.      ".previous\n"
  224.      ".section __ex_table,\"a\"\n"
  225.      "   .align 4\n"
  226.      "   .long 1b,60b\n"
  227.      "   .long 22b,6b\n"
  228.      "   .long 2b,6b\n"
  229.      "   .long 24b,7b\n"
  230.      "   .long 3b,60b\n"
  231.      "   .long 4b,7b\n"
  232.      "   .long 25b,8b\n"
  233.      "   .long 5b,8b\n"
  234.      ".previous"
  235.      : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  236.      : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
  237.      : "memory");
  238.     return n;
  239. }
  240.  
  241. #define __copy_from_user_big(to, from, n, fixup, copy)    \
  242.     __asm__ __volatile__                \
  243.     ("10: movesl (%1)+,%%d0\n"            \
  244.      "    movel %%d0,(%0)+\n"            \
  245.      "    subql #1,%2\n"                \
  246.      "    jne 10b\n"                \
  247.      ".section .fixup,\"ax\"\n"            \
  248.      "    .even\n"                    \
  249.      "11: movel %2,%%d0\n"                \
  250.      "13: clrl (%0)+\n"                \
  251.      "    subql #1,%%d0\n"                \
  252.      "    jne 13b\n"                \
  253.      "    lsll #2,%2\n"                \
  254.      fixup "\n"                    \
  255.      "    jra 12f\n"                \
  256.      ".previous\n"                    \
  257.      ".section __ex_table,\"a\"\n"            \
  258.      "    .align 4\n"                \
  259.      "    .long 10b,11b\n"                \
  260.      ".previous\n"                    \
  261.      copy "\n"                    \
  262.      "12:"                        \
  263.      : "=a"(to), "=a"(from), "=d"(n)        \
  264.      : "0"(to), "1"(from), "2"(n/4)            \
  265.      : "d0", "memory")
  266.  
  267. static inline unsigned long
  268. __constant_copy_from_user(void *to, const void *from, unsigned long n)
  269. {
  270.     switch (n) {
  271.     case 0:
  272.     break;
  273.     case 1:
  274.     __asm__ __volatile__
  275.         ("1: movesb (%1)+,%%d0\n"
  276.          "   moveb %%d0,(%0)+\n"
  277.          "2:\n"
  278.          ".section .fixup,\"ax\"\n"
  279.          "   .even\n"
  280.          "3: addql #1,%2\n"
  281.          "   clrb (%0)+\n"
  282.          "   jra 2b\n"
  283.          ".previous\n"
  284.          ".section __ex_table,\"a\"\n"
  285.          "   .align 4\n"
  286.          "   .long 1b,3b\n"
  287.          ".previous"
  288.          : "=a"(to), "=a"(from), "=d"(n)
  289.          : "0"(to), "1"(from), "2"(0)
  290.          : "d0", "memory");
  291.     break;
  292.     case 2:
  293.     __asm__ __volatile__
  294.         ("1: movesw (%1)+,%%d0\n"
  295.          "   movew %%d0,(%0)+\n"
  296.          "2:\n"
  297.          ".section .fixup,\"ax\"\n"
  298.          "   .even\n"
  299.          "3: addql #2,%2\n"
  300.          "   clrw (%0)+\n"
  301.          "   jra 2b\n"
  302.          ".previous\n"
  303.          ".section __ex_table,\"a\"\n"
  304.          "   .align 4\n"
  305.          "   .long 1b,3b\n"
  306.          ".previous"
  307.          : "=a"(to), "=a"(from), "=d"(n)
  308.          : "0"(to), "1"(from), "2"(0)
  309.          : "d0", "memory");
  310.     break;
  311.     case 3:
  312.     __asm__ __volatile__
  313.         ("1: movesw (%1)+,%%d0\n"
  314.          "   movew %%d0,(%0)+\n"
  315.          "2: movesb (%1)+,%%d0\n"
  316.          "   moveb %%d0,(%0)+\n"
  317.          "3:"
  318.          ".section .fixup,\"ax\"\n"
  319.          "   .even\n"
  320.          "4: addql #2,%2\n"
  321.          "   clrw (%0)+\n"
  322.          "5: addql #1,%2\n"
  323.          "   clrb (%0)+\n"
  324.          "   jra 3b\n"
  325.          ".previous\n"
  326.          ".section __ex_table,\"a\"\n"
  327.          "   .align 4\n"
  328.          "   .long 1b,4b\n"
  329.          "   .long 2b,5b\n"
  330.          ".previous"
  331.          : "=a"(to), "=a"(from), "=d"(n)
  332.          : "0"(to), "1"(from), "2"(0)
  333.          : "d0", "memory");
  334.     break;
  335.     case 4:
  336.     __asm__ __volatile__
  337.         ("1: movesl (%1)+,%%d0\n"
  338.          "   movel %%d0,(%0)+\n"
  339.          "2:"
  340.          ".section .fixup,\"ax\"\n"
  341.          "   .even\n"
  342.          "3: addql #4,%2\n"
  343.          "   clrl (%0)+\n"
  344.          "   jra 2b\n"
  345.          ".previous\n"
  346.          ".section __ex_table,\"a\"\n"
  347.          "   .align 4\n"
  348.          "   .long 1b,3b\n"
  349.          ".previous"
  350.          : "=a"(to), "=a"(from), "=d"(n)
  351.          : "0"(to), "1"(from), "2"(0)
  352.          : "d0", "memory");
  353.     break;
  354.     case 8:
  355.     __asm__ __volatile__
  356.         ("1: movesl (%1)+,%%d0\n"
  357.          "   movel %%d0,(%0)+\n"
  358.          "2: movesl (%1)+,%%d0\n"
  359.          "   movel %%d0,(%0)+\n"
  360.          "3:"
  361.          ".section .fixup,\"ax\"\n"
  362.          "   .even\n"
  363.          "4: addql #4,%2\n"
  364.          "   clrl (%0)+\n"
  365.          "5: addql #4,%2\n"
  366.          "   clrl (%0)+\n"
  367.          "   jra 3b\n"
  368.          ".previous\n"
  369.          ".section __ex_table,\"a\"\n"
  370.          "   .align 4\n"
  371.          "   .long 1b,4b\n"
  372.          "   .long 2b,5b\n"
  373.          ".previous"
  374.          : "=a"(to), "=a"(from), "=d"(n)
  375.          : "0"(to), "1"(from), "2"(0)
  376.          : "d0", "memory");
  377.     break;
  378.     case 12:
  379.     __asm__ __volatile__
  380.         ("1: movesl (%1)+,%%d0\n"
  381.          "   movel %%d0,(%0)+\n"
  382.          "2: movesl (%1)+,%%d0\n"
  383.          "   movel %%d0,(%0)+\n"
  384.          "3: movesl (%1)+,%%d0\n"
  385.          "   movel %%d0,(%0)+\n"
  386.          "4:"
  387.          ".section .fixup,\"ax\"\n"
  388.          "   .even\n"
  389.          "5: addql #4,%2\n"
  390.          "   clrl (%0)+\n"
  391.          "6: addql #4,%2\n"
  392.          "   clrl (%0)+\n"
  393.          "7: addql #4,%2\n"
  394.          "   clrl (%0)+\n"
  395.          "   jra 4b\n"
  396.          ".previous\n"
  397.          ".section __ex_table,\"a\"\n"
  398.          "   .align 4\n"
  399.          "   .long 1b,5b\n"
  400.          "   .long 2b,6b\n"
  401.          "   .long 3b,7b\n"
  402.          ".previous"
  403.          : "=a"(to), "=a"(from), "=d"(n)
  404.          : "0"(to), "1"(from), "2"(0)
  405.          : "d0", "memory");
  406.     break;
  407.     case 16:
  408.     __asm__ __volatile__
  409.         ("1: movesl (%1)+,%%d0\n"
  410.          "   movel %%d0,(%0)+\n"
  411.          "2: movesl (%1)+,%%d0\n"
  412.          "   movel %%d0,(%0)+\n"
  413.          "3: movesl (%1)+,%%d0\n"
  414.          "   movel %%d0,(%0)+\n"
  415.          "4: movesl (%1)+,%%d0\n"
  416.          "   movel %%d0,(%0)+\n"
  417.          "5:"
  418.          ".section .fixup,\"ax\"\n"
  419.          "   .even\n"
  420.          "6: addql #4,%2\n"
  421.          "   clrl (%0)+\n"
  422.          "7: addql #4,%2\n"
  423.          "   clrl (%0)+\n"
  424.          "8: addql #4,%2\n"
  425.          "   clrl (%0)+\n"
  426.          "9: addql #4,%2\n"
  427.          "   clrl (%0)+\n"
  428.          "   jra 5b\n"
  429.          ".previous\n"
  430.          ".section __ex_table,\"a\"\n"
  431.          "   .align 4\n"
  432.          "   .long 1b,6b\n"
  433.          "   .long 2b,7b\n"
  434.          "   .long 3b,8b\n"
  435.          "   .long 4b,9b\n"
  436.          ".previous"
  437.          : "=a"(to), "=a"(from), "=d"(n)
  438.          : "0"(to), "1"(from), "2"(0)
  439.          : "d0", "memory");
  440.     break;
  441.     default:
  442.     switch (n & 3) {
  443.     case 0:
  444.         __copy_from_user_big(to, from, n, "", "");
  445.         break;
  446.     case 1:
  447.         __copy_from_user_big(to, from, n,
  448.                  /* fixup */
  449.                  "1: addql #1,%2\n"
  450.                  "   clrb (%0)+",
  451.                  /* copy */
  452.                  "2: movesb (%1)+,%%d0\n"
  453.                  "   moveb %%d0,(%0)+\n"
  454.                  ".section __ex_table,\"a\"\n"
  455.                  "   .long 2b,1b\n"
  456.                  ".previous");
  457.         break;
  458.     case 2:
  459.         __copy_from_user_big(to, from, n,
  460.                  /* fixup */
  461.                  "1: addql #2,%2\n"
  462.                  "   clrw (%0)+",
  463.                  /* copy */
  464.                  "2: movesw (%1)+,%%d0\n"
  465.                  "   movew %%d0,(%0)+\n"
  466.                  ".section __ex_table,\"a\"\n"
  467.                  "   .long 2b,1b\n"
  468.                  ".previous");
  469.         break;
  470.     case 3:
  471.         __copy_from_user_big(to, from, n,
  472.                  /* fixup */
  473.                  "1: addql #2,%2\n"
  474.                  "   clrw (%0)+\n"
  475.                  "2: addql #1,%2\n"
  476.                  "   clrb (%0)+",
  477.                  /* copy */
  478.                  "3: movesw (%1)+,%%d0\n"
  479.                  "   movew %%d0,(%0)+\n"
  480.                  "4: movesb (%1)+,%%d0\n"
  481.                  "   moveb %%d0,(%0)+\n"
  482.                  ".section __ex_table,\"a\"\n"
  483.                  "   .long 3b,1b\n"
  484.                  "   .long 4b,2b\n"
  485.                  ".previous");
  486.         break;
  487.     }
  488.     break;
  489.     }
  490.     return n;
  491. }
  492.  
  493. #define __copy_to_user_big(to, from, n, fixup, copy)    \
  494.     __asm__ __volatile__                \
  495.     ("10: movel (%1)+,%%d0\n"            \
  496.      "31: movesl %%d0,(%0)+\n"            \
  497.      "11: subql #1,%2\n"                \
  498.      "    jne 10b\n"                \
  499.      "41:\n"                    \
  500.      ".section .fixup,\"ax\"\n"            \
  501.      "   .even\n"                    \
  502.      "22: addql #1,%2\n"                \
  503.      "12: lsll #2,%2\n"                \
  504.      fixup "\n"                    \
  505.      "    jra 13f\n"                \
  506.      ".previous\n"                    \
  507.      ".section __ex_table,\"a\"\n"            \
  508.      "    .align 4\n"                \
  509.      "    .long 10b,22b\n"                \
  510.      "    .long 31b,12b\n"                \
  511.      "    .long 11b,12b\n"                \
  512.      "    .long 41b,22b\n"                \
  513.      ".previous\n"                    \
  514.      copy "\n"                    \
  515.      "13:"                        \
  516.      : "=a"(to), "=a"(from), "=d"(n)        \
  517.      : "0"(to), "1"(from), "2"(n/4)            \
  518.      : "d0", "memory")
  519.  
  520. static inline unsigned long
  521. __constant_copy_to_user(void *to, const void *from, unsigned long n)
  522. {
  523.     switch (n) {
  524.     case 0:
  525.     break;
  526.     case 1:
  527.     __asm__ __volatile__
  528.         ("   moveb (%1)+,%%d0\n"
  529.          "21:movesb %%d0,(%0)+\n"
  530.          "1:\n"
  531.          ".section .fixup,\"ax\"\n"
  532.          "   .even\n"
  533.          "2: addql #1,%2\n"
  534.          "   jra 1b\n"
  535.          ".previous\n"
  536.          ".section __ex_table,\"a\"\n"
  537.          "   .align 4\n  "
  538.          "   .long 21b,2b\n"
  539.          "   .long 1b,2b\n"
  540.          ".previous"
  541.          : "=a"(to), "=a"(from), "=d"(n)
  542.          : "0"(to), "1"(from), "2"(0)
  543.          : "d0", "memory");
  544.     break;
  545.     case 2:
  546.     __asm__ __volatile__
  547.         ("   movew (%1)+,%%d0\n"
  548.          "21:movesw %%d0,(%0)+\n"
  549.          "1:\n"
  550.          ".section .fixup,\"ax\"\n"
  551.          "   .even\n"
  552.          "2: addql #2,%2\n"
  553.          "   jra 1b\n"
  554.          ".previous\n"
  555.          ".section __ex_table,\"a\"\n"
  556.          "   .align 4\n"
  557.          "   .long 21b,2b\n"
  558.          "   .long 1b,2b\n"
  559.          ".previous"
  560.          : "=a"(to), "=a"(from), "=d"(n)
  561.          : "0"(to), "1"(from), "2"(0)
  562.          : "d0", "memory");
  563.     break;
  564.     case 3:
  565.     __asm__ __volatile__
  566.         ("   movew (%1)+,%%d0\n"
  567.          "21:movesw %%d0,(%0)+\n"
  568.          "1: moveb (%1)+,%%d0\n"
  569.          "22:movesb %%d0,(%0)+\n"
  570.          "2:\n"
  571.          ".section .fixup,\"ax\"\n"
  572.          "   .even\n"
  573.          "3: addql #2,%2\n"
  574.          "4: addql #1,%2\n"
  575.          "   jra 2b\n"
  576.          ".previous\n"
  577.          ".section __ex_table,\"a\"\n"
  578.          "   .align 4\n"
  579.          "   .long 21b,3b\n"
  580.          "   .long 1b,3b\n"
  581.          "   .long 22b,4b\n"
  582.          "   .long 2b,4b\n"
  583.          ".previous"
  584.          : "=a"(to), "=a"(from), "=d"(n)
  585.          : "0"(to), "1"(from), "2"(0)
  586.          : "d0", "memory");
  587.     break;
  588.     case 4:
  589.     __asm__ __volatile__
  590.         ("   movel (%1)+,%%d0\n"
  591.          "21:movesl %%d0,(%0)+\n"
  592.          "1:\n"
  593.          ".section .fixup,\"ax\"\n"
  594.          "   .even\n"
  595.          "2: addql #4,%2\n"
  596.          "   jra 1b\n"
  597.          ".previous\n"
  598.          ".section __ex_table,\"a\"\n"
  599.          "   .align 4\n"
  600.          "   .long 21b,2b\n"
  601.          "   .long 1b,2b\n"
  602.          ".previous"
  603.          : "=a"(to), "=a"(from), "=d"(n)
  604.          : "0"(to), "1"(from), "2"(0)
  605.          : "d0", "memory");
  606.     break;
  607.     case 8:
  608.     __asm__ __volatile__
  609.         ("   movel (%1)+,%%d0\n"
  610.          "21:movesl %%d0,(%0)+\n"
  611.          "1: movel (%1)+,%%d0\n"
  612.          "22:movesl %%d0,(%0)+\n"
  613.          "2:\n"
  614.          ".section .fixup,\"ax\"\n"
  615.          "   .even\n"
  616.          "3: addql #4,%2\n"
  617.          "4: addql #4,%2\n"
  618.          "   jra 2b\n"
  619.          ".previous\n"
  620.          ".section __ex_table,\"a\"\n"
  621.          "   .align 4\n"
  622.          "   .long 21b,3b\n"
  623.          "   .long 1b,3b\n"
  624.          "   .long 22b,4b\n"
  625.          "   .long 2b,4b\n"
  626.          ".previous"
  627.          : "=a"(to), "=a"(from), "=d"(n)
  628.          : "0"(to), "1"(from), "2"(0)
  629.          : "d0", "memory");
  630.     break;
  631.     case 12:
  632.     __asm__ __volatile__
  633.         ("   movel (%1)+,%%d0\n"
  634.          "21:movesl %%d0,(%0)+\n"
  635.          "1: movel (%1)+,%%d0\n"
  636.          "22:movesl %%d0,(%0)+\n"
  637.          "2: movel (%1)+,%%d0\n"
  638.          "23:movesl %%d0,(%0)+\n"
  639.          "3:\n"
  640.          ".section .fixup,\"ax\"\n"
  641.          "   .even\n"
  642.          "4: addql #4,%2\n"
  643.          "5: addql #4,%2\n"
  644.          "6: addql #4,%2\n"
  645.          "   jra 3b\n"
  646.          ".previous\n"
  647.          ".section __ex_table,\"a\"\n"
  648.          "   .align 4\n"
  649.          "   .long 21b,4b\n"
  650.          "   .long 1b,4b\n"
  651.          "   .long 22b,5b\n"
  652.          "   .long 2b,5b\n"
  653.          "   .long 23b,6b\n"
  654.          "   .long 3b,6b\n"
  655.          ".previous"
  656.          : "=a"(to), "=a"(from), "=d"(n)
  657.          : "0"(to), "1"(from), "2"(0)
  658.          : "d0", "memory");
  659.     break;
  660.     case 16:
  661.     __asm__ __volatile__
  662.         ("   movel (%1)+,%%d0\n"
  663.          "21:movesl %%d0,(%0)+\n"
  664.          "1: movel (%1)+,%%d0\n"
  665.          "22:movesl %%d0,(%0)+\n"
  666.          "2: movel (%1)+,%%d0\n"
  667.          "23:movesl %%d0,(%0)+\n"
  668.          "3: movel (%1)+,%%d0\n"
  669.          "24:movesl %%d0,(%0)+\n"
  670.          "4:"
  671.          ".section .fixup,\"ax\"\n"
  672.          "   .even\n"
  673.          "5: addql #4,%2\n"
  674.          "6: addql #4,%2\n"
  675.          "7: addql #4,%2\n"
  676.          "8: addql #4,%2\n"
  677.          "   jra 4b\n"
  678.          ".previous\n"
  679.          ".section __ex_table,\"a\"\n"
  680.          "   .align 4\n"
  681.          "   .long 21b,5b\n"
  682.          "   .long 1b,5b\n"
  683.          "   .long 22b,6b\n"
  684.          "   .long 2b,6b\n"
  685.          "   .long 23b,7b\n"
  686.          "   .long 3b,7b\n"
  687.          "   .long 24b,8b\n"
  688.          "   .long 4b,8b\n"
  689.          ".previous"
  690.          : "=a"(to), "=a"(from), "=d"(n)
  691.          : "0"(to), "1"(from), "2"(0)
  692.          : "d0", "memory");
  693.     break;
  694.     default:
  695.     switch (n & 3) {
  696.     case 0:
  697.         __copy_to_user_big(to, from, n, "", "");
  698.         break;
  699.     case 1:
  700.         __copy_to_user_big(to, from, n,
  701.                    /* fixup */
  702.                    "1: addql #1,%2",
  703.                    /* copy */
  704.                    "   moveb (%1)+,%%d0\n"
  705.                    "22:movesb %%d0,(%0)+\n"
  706.                    "2:"
  707.                    ".section __ex_table,\"a\"\n"
  708.                    "   .long 22b,1b\n"
  709.                    "   .long 2b,1b\n"
  710.                    ".previous");
  711.         break;
  712.     case 2:
  713.         __copy_to_user_big(to, from, n,
  714.                    /* fixup */
  715.                    "1: addql #2,%2",
  716.                    /* copy */
  717.                    "   movew (%1)+,%%d0\n"
  718.                    "22:movesw %%d0,(%0)+\n"
  719.                    "2:"
  720.                    ".section __ex_table,\"a\"\n"
  721.                    "   .long 22b,1b\n"
  722.                    "   .long 2b,1b\n"
  723.                    ".previous");
  724.         break;
  725.     case 3:
  726.         __copy_to_user_big(to, from, n,
  727.                    /* fixup */
  728.                    "1: addql #2,%2\n"
  729.                    "2: addql #1,%2",
  730.                    /* copy */
  731.                    "   movew (%1)+,%%d0\n"
  732.                    "23:movesw %%d0,(%0)+\n"
  733.                    "3: moveb (%1)+,%%d0\n"
  734.                    "24:movesb %%d0,(%0)+\n"
  735.                    "4:"
  736.                    ".section __ex_table,\"a\"\n"
  737.                    "   .long 23b,1b\n"
  738.                    "   .long 3b,1b\n"
  739.                    "   .long 24b,2b\n"
  740.                    "   .long 4b,2b\n"
  741.                    ".previous");
  742.         break;
  743.     }
  744.     break;
  745.     }
  746.     return n;
  747. }
  748.  
  749. #define copy_from_user(to, from, n)        \
  750. (__builtin_constant_p(n) ?            \
  751.  __constant_copy_from_user(to, from, n) :    \
  752.  __generic_copy_from_user(to, from, n))
  753.  
  754. #define copy_to_user(to, from, n)        \
  755. (__builtin_constant_p(n) ?            \
  756.  __constant_copy_to_user(to, from, n) :        \
  757.  __generic_copy_to_user(to, from, n))
  758.  
  759. #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
  760. #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
  761.  
  762. /*
  763.  * Copy a null terminated string from userspace.
  764.  */
  765.  
  766. static inline long
  767. strncpy_from_user(char *dst, const char *src, long count)
  768. {
  769.     long res;
  770.     if (count == 0) return count;
  771.     __asm__ __volatile__
  772.     ("1: movesb (%2)+,%%d0\n"
  773.      "12:moveb %%d0,(%1)+\n"
  774.      "   jeq 2f\n"
  775.      "   subql #1,%3\n"
  776.      "   jne 1b\n"
  777.      "2: subl %3,%0\n"
  778.      "3:\n"
  779.      ".section .fixup,\"ax\"\n"
  780.      "   .even\n"
  781.      "4: movel %4,%0\n"
  782.      "   jra 3b\n"
  783.      ".previous\n"
  784.      ".section __ex_table,\"a\"\n"
  785.      "   .align 4\n"
  786.      "   .long 1b,4b\n"
  787.      "   .long 12b,4b\n"
  788.      ".previous"
  789.      : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
  790.      : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
  791.      : "d0", "memory");
  792.     return res;
  793. }
  794.  
  795. /*
  796.  * Return the size of a string (including the ending 0)
  797.  *
  798.  * Return 0 for error
  799.  */
  800. static inline long strlen_user(const char * src)
  801. {
  802.     long res = -(long) src;
  803.     __asm__ __volatile__
  804.     ("1: movesb (%1)+,%%d0\n"
  805.      "12:tstb %%d0\n"
  806.      "   jne 1b\n"
  807.      "   addl %1,%0\n"
  808.      "2:\n"
  809.      ".section .fixup,\"ax\"\n"
  810.      "   .even\n"
  811.      "3: moveq %2,%0\n"
  812.      "   jra 2b\n"
  813.      ".previous\n"
  814.      ".section __ex_table,\"a\"\n"
  815.      "   .align 4\n"
  816.      "   .long 1b,3b\n"
  817.      "   .long 12b,3b\n"
  818.      ".previous"
  819.      : "=d"(res), "=a"(src)
  820.      : "i"(0), "0"(res), "1"(src)
  821.      : "d0");
  822.     return res;
  823. }
  824.  
  825. /*
  826.  * Zero Userspace
  827.  */
  828.  
  829. static inline unsigned long
  830. clear_user(void *to, unsigned long n)
  831. {
  832.     __asm__ __volatile__
  833.     ("   tstl %1\n"
  834.      "   jeq 3f\n"
  835.      "1: movesl %3,(%0)+\n"
  836.      "2: subql #1,%1\n"
  837.      "   jne 1b\n"
  838.      "3: movel %2,%1\n"
  839.      "   bclr #1,%1\n"
  840.      "   jeq 4f\n"
  841.      "24:movesw %3,(%0)+\n"
  842.      "4: bclr #0,%1\n"
  843.      "   jeq 5f\n"
  844.      "25:movesb %3,(%0)+\n"
  845.      "5:\n"
  846.      ".section .fixup,\"ax\"\n"
  847.      "   .even\n"
  848.      "61:addql #1,%1\n"
  849.      "6: lsll #2,%1\n"
  850.      "   addl %2,%1\n"
  851.      "   jra 5b\n"
  852.      "7: addql #2,%1\n"
  853.      "   jra 5b\n"
  854.      "8: addql #1,%1\n"
  855.      "   jra 5b\n"
  856.      ".previous\n"
  857.      ".section __ex_table,\"a\"\n"
  858.      "   .align 4\n"
  859.      "   .long 1b,61b\n"
  860.      "   .long 2b,6b\n"
  861.      "   .long 3b,61b\n"
  862.      "   .long 24b,7b\n"
  863.      "   .long 4b,7b\n"
  864.      "   .long 25b,8b\n"
  865.      "   .long 5b,8b\n"
  866.      ".previous"
  867.      : "=a"(to), "=d"(n)
  868.      : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
  869.     return n;
  870. }
  871.  
  872. #endif /* _M68K_UACCESS_H */
  873.